{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# IMIT for Portfolio Management on DJ30\n",
    "This tutorial is to demonstrate an example of using IMIT to do portfolio management on DJ30\n",
    "\n",
    "However, it is highly suggested to run the code [here](https://github.com/qinmoelei/TradeMaster_reframe/blob/master/agent/Investor_Imitator/logic_discriptor/logic_discriptor.py) to train the logic descriptors and run the code [here](https://github.com/qinmoelei/TradeMaster_reframe/blob/master/agent/Investor_Imitator/RL/RL.py) to train the DPG using the python file instead of using this jupyter notebook.\n",
    "\n",
    "It will take <font color=\"red\">hours</font> to run the notebook.\n",
    "## Set up Experinment Environment"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from IPython.display import clear_output\n",
    "import argparse\n",
    "import sys\n",
    "import numpy as np\n",
    "import torch\n",
    "from torch import nn\n",
    "import yaml\n",
    "import os\n",
    "import pandas as pd\n",
    "module_path = os.path.abspath(os.path.join('..'))\n",
    "sys.path.append(module_path)\n",
    "requirements_path=module_path+\"/requirements.txt\"\n",
    "print(requirements_path)\n",
    "command=\"pip install -r \"+requirements_path\n",
    "os.system(command)\n",
    "clear_output(wait=True)\n",
    "! conda install pytorch torchvision torchaudio cudatoolkit=11.3 -c pytorch\n",
    "clear_output(wait=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Download and Preprocess the Data\n",
    "The dataconfig part in TradeMaster is shared by all other parts, it is worth noticing that for algorithms trading, only the dataset BTC is supported.\n",
    "\n",
    "The following code will help to download the data in the folder [.data/data/dj30](https://github.com/qinmoelei/TradeMaster_reframe/tree/master/tutorial/data/data/dj30), where 4 files could be found: the whole data and train, valid and test data which will be used when we try to construct the RL environment for the agent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from data.download_data import Dataconfig\n",
    "parser = argparse.ArgumentParser()\n",
    "\n",
    "parser.add_argument(\"--data_path\",\n",
    "                    type=str,\n",
    "                    default=\"./data/data/\",\n",
    "                    help=\"the path for storing the downloaded data\")\n",
    "#where we store the dataset\n",
    "parser.add_argument(\n",
    "    \"--output_config_path\",\n",
    "    type=str,\n",
    "    default=\"./config/output_config/data\",\n",
    "    help=\"the path for storing the generated config file for data\")\n",
    "# where we store the config file\n",
    "parser.add_argument(\n",
    "    \"--dataset\",\n",
    "    choices=[\"exchange\",\"dj30\",\"sz50\",\"crypto\"],\n",
    "    default=\"dj30\",\n",
    "    help=\"the name of the dataset\",\n",
    ")\n",
    "parser.add_argument(\"--split_proportion\",\n",
    "                    type=list,\n",
    "                    default=[0.8, 0.1, 0.1],\n",
    "                    help=\"the split proportion for train, valid and test\")\n",
    "parser.add_argument(\n",
    "    \"--generate_config\",\n",
    "    type=bool,\n",
    "    default=False,\n",
    "    help=\n",
    "    \"determine whether to generate a yaml file to memorize the train valid and test'data's dict\"\n",
    ")\n",
    "parser.add_argument(\n",
    "    \"--input_config\",\n",
    "    type=bool,\n",
    "    default=False,\n",
    "    help=\n",
    "    \"determine whether to use a yaml file as the overall input of the Dataconfig, this is needed when have other format of dataset\"\n",
    ")\n",
    "\n",
    "parser.add_argument(\n",
    "    \"--input_config_path\",\n",
    "    type=str,\n",
    "    default=\"config/input_config/data/custom.yml\",\n",
    "    help=\n",
    "    \"determine the location of a yaml file used to initialize the Dataconfig Class\"\n",
    ")\n",
    "args = parser.parse_args(args=[])\n",
    "a = Dataconfig(args)\n",
    "clear_output(wait=True)\n",
    "clear_output(wait=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The preprocessed data follows the following structure:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "data=pd.read_csv(\"data/data/dj30/dj30.csv\",index_col=0)\n",
    "data.head(5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## IMIT Enviornment Construction, logic descriptor training and picking, Agent Training, Model Picking and Testing\n",
    "### Logic Descriptor Training and Picking"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/sunshuo/miniconda3/envs/TradeMaster/lib/python3.7/site-packages/tqdm/auto.py:22: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
      "  from .autonotebook import tqdm as notebook_tqdm\n",
      "/home/sunshuo/qml/TradeMaster/tutorial/data/preprocess.py:19: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  (temp_indicator.close.rolling(2).sum() - temp_indicator.close)) - 1\n",
      "/home/sunshuo/qml/TradeMaster/tutorial/data/preprocess.py:21: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  5) / temp_indicator.adjcp - 1\n",
      "/home/sunshuo/qml/TradeMaster/tutorial/data/preprocess.py:23: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  10) / temp_indicator.adjcp - 1\n",
      "/home/sunshuo/qml/TradeMaster/tutorial/data/preprocess.py:25: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  15) / temp_indicator.adjcp - 1\n",
      "/home/sunshuo/qml/TradeMaster/tutorial/data/preprocess.py:27: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  20) / temp_indicator.adjcp - 1\n",
      "/home/sunshuo/qml/TradeMaster/tutorial/data/preprocess.py:29: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  25) / temp_indicator.adjcp - 1\n",
      "/home/sunshuo/qml/TradeMaster/tutorial/data/preprocess.py:31: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  30) / temp_indicator.adjcp - 1\n"
     ]
    },
    {
     "ename": "KeyboardInterrupt",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mKeyboardInterrupt\u001b[0m                         Traceback (most recent call last)",
      "\u001b[0;32m/tmp/ipykernel_3905793/1823899856.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m    118\u001b[0m )\n\u001b[1;32m    119\u001b[0m \u001b[0margs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mparser\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mparse_args\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 120\u001b[0;31m \u001b[0ma\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlogic_discriptor\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;32m~/qml/TradeMaster/tutorial/agent/Investor_Imitator/logic_discriptor/logic_discriptor.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, args)\u001b[0m\n\u001b[1;32m    162\u001b[0m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdf_train_list\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mAR_train_list\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mMDD_train_list\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mSR_train_list\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mER_train_list\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;31m\\\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    163\u001b[0m              self.WR_train_list = make_label_tic(\n\u001b[0;32m--> 164\u001b[0;31m             args.num_day, self.dataconfig.train_dataset)\n\u001b[0m\u001b[1;32m    165\u001b[0m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdf_valid_list\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mAR_valid_list\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mMDD_valid_list\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mSR_valid_list\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mER_valid_list\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;31m\\\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    166\u001b[0m              self.WR_valid_list = make_label_tic(\n",
      "\u001b[0;32m~/qml/TradeMaster/tutorial/agent/Investor_Imitator/logic_discriptor/utli.py\u001b[0m in \u001b[0;36mmake_label_tic\u001b[0;34m(num_day, df)\u001b[0m\n\u001b[1;32m     38\u001b[0m             \u001b[0;32mfor\u001b[0m \u001b[0mdex\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindex\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mnum_day\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     39\u001b[0m                 \u001b[0mold_price\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdf_tic\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mdf_tic\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mindex\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mdex\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 40\u001b[0;31m                 \u001b[0mnew_price\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdf_tic\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mdf_tic\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mindex\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mdex\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     41\u001b[0m                 return_rate = (float(new_price.close) /\n\u001b[1;32m     42\u001b[0m                                float(old_price.close)) - 1\n",
      "\u001b[0;32m~/miniconda3/envs/TradeMaster/lib/python3.7/site-packages/pandas/core/ops/common.py\u001b[0m in \u001b[0;36mnew_method\u001b[0;34m(self, other)\u001b[0m\n\u001b[1;32m     67\u001b[0m         \u001b[0mother\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mitem_from_zerodim\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mother\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     68\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 69\u001b[0;31m         \u001b[0;32mreturn\u001b[0m \u001b[0mmethod\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     70\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     71\u001b[0m     \u001b[0;32mreturn\u001b[0m \u001b[0mnew_method\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/miniconda3/envs/TradeMaster/lib/python3.7/site-packages/pandas/core/arraylike.py\u001b[0m in \u001b[0;36m__eq__\u001b[0;34m(self, other)\u001b[0m\n\u001b[1;32m     30\u001b[0m     \u001b[0;34m@\u001b[0m\u001b[0munpack_zerodim_and_defer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"__eq__\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     31\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0m__eq__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 32\u001b[0;31m         \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_cmp_method\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mother\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moperator\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0meq\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     33\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     34\u001b[0m     \u001b[0;34m@\u001b[0m\u001b[0munpack_zerodim_and_defer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"__ne__\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/miniconda3/envs/TradeMaster/lib/python3.7/site-packages/pandas/core/indexes/base.py\u001b[0m in \u001b[0;36m_cmp_method\u001b[0;34m(self, other, op)\u001b[0m\n\u001b[1;32m   6059\u001b[0m         \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   6060\u001b[0m             \u001b[0;32mwith\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0merrstate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mall\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"ignore\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 6061\u001b[0;31m                 \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mops\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcomparison_op\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_values\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mop\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   6062\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   6063\u001b[0m         \u001b[0;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/miniconda3/envs/TradeMaster/lib/python3.7/site-packages/pandas/core/ops/array_ops.py\u001b[0m in \u001b[0;36mcomparison_op\u001b[0;34m(left, right, op)\u001b[0m\n\u001b[1;32m    277\u001b[0m             \u001b[0mres_values\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mzeros\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlvalues\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mbool\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    278\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 279\u001b[0;31m     \u001b[0;32melif\u001b[0m \u001b[0mis_numeric_v_string_like\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlvalues\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrvalues\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    280\u001b[0m         \u001b[0;31m# GH#36377 going through the numexpr path would incorrectly raise\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    281\u001b[0m         \u001b[0;32mreturn\u001b[0m \u001b[0minvalid_comparison\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlvalues\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrvalues\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mop\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/miniconda3/envs/TradeMaster/lib/python3.7/site-packages/pandas/core/dtypes/common.py\u001b[0m in \u001b[0;36mis_numeric_v_string_like\u001b[0;34m(a, b)\u001b[0m\n\u001b[1;32m   1067\u001b[0m     \u001b[0mis_b_array\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mb\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mndarray\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1068\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1069\u001b[0;31m     \u001b[0mis_a_numeric_array\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mis_a_array\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdtype\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkind\u001b[0m \u001b[0;32min\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m\"u\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"i\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"f\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"c\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"b\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   1070\u001b[0m     \u001b[0mis_b_numeric_array\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mis_b_array\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mb\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdtype\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkind\u001b[0m \u001b[0;32min\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m\"u\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"i\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"f\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"c\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"b\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1071\u001b[0m     \u001b[0mis_a_string_array\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mis_a_array\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdtype\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkind\u001b[0m \u001b[0;32min\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m\"S\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"U\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
     ]
    }
   ],
   "source": [
    "from agent.Investor_Imitator.logic_discriptor.logic_discriptor import logic_discriptor\n",
    "import argparse\n",
    "\n",
    "parser = argparse.ArgumentParser()\n",
    "\n",
    "parser.add_argument(\"--data_path\",\n",
    "                    type=str,\n",
    "                    default=\"./data/data/\",\n",
    "                    help=\"the path for storing the downloaded data\")\n",
    "\n",
    "#where we store the dataset\n",
    "parser.add_argument(\n",
    "    \"--output_config_path\",\n",
    "    type=str,\n",
    "    default=\"config/output_config/data\",\n",
    "    help=\"the path for storing the generated config file for data\")\n",
    "\n",
    "# where we store the config file\n",
    "parser.add_argument(\n",
    "    \"--dataset\",\n",
    "    choices=[\"dj30\", \"sz50\", \"acl18\", \"futures\", \"crypto\", \"exchange\"],\n",
    "    default=\"dj30\",\n",
    "    help=\"the name of the dataset\",\n",
    ")\n",
    "\n",
    "parser.add_argument(\"--split_proportion\",\n",
    "                    type=list,\n",
    "                    default=[0.8, 0.1, 0.1],\n",
    "                    help=\"the split proportion for train, valid and test\")\n",
    "\n",
    "parser.add_argument(\n",
    "    \"--generate_config\",\n",
    "    type=bool,\n",
    "    default=True,\n",
    "    help=\n",
    "    \"determine whether to generate a yaml file to memorize the train valid and test'data's dict\"\n",
    ")\n",
    "\n",
    "parser.add_argument(\n",
    "    \"--input_config\",\n",
    "    type=bool,\n",
    "    default=False,\n",
    "    help=\n",
    "    \"determine whether to use a yaml file as the overall input of the Dataconfig, this is needed when have other format of dataset\"\n",
    ")\n",
    "\n",
    "parser.add_argument(\n",
    "    \"--input_config_path\",\n",
    "    type=str,\n",
    "    default=\"config/input_config/data/custom.yml\",\n",
    "    help=\n",
    "    \"determine the location of a yaml file used to initialize the Dataconfig Class\"\n",
    ")\n",
    "\n",
    "parser.add_argument(\n",
    "    \"--discriptor_path\",\n",
    "    type=str,\n",
    "    default=\"./result/PM/invest_imitator/logic_discriptor\",\n",
    "    help=\"the path for storing the generated logic_discriptor file for data\")\n",
    "\n",
    "parser.add_argument(\"--seed\",\n",
    "                    type=int,\n",
    "                    default=12345,\n",
    "                    help=\"the random seed to train the logic discriptor\")\n",
    "\n",
    "parser.add_argument(\"--num_day\",\n",
    "                    type=int,\n",
    "                    default=10,\n",
    "                    help=\"the number of the day for us to make the label\")\n",
    "\n",
    "parser.add_argument(\n",
    "    \"--rank_name_list\",\n",
    "    type=list,\n",
    "    default=[\"AR\", \"SR\", \"MDD\", \"ER\", \"WR\"],\n",
    "    help=\n",
    "    \"the list of the name of indicator we use to train the logic discriptor\")\n",
    "\n",
    "parser.add_argument(\n",
    "    \"--batch_size\",\n",
    "    type=int,\n",
    "    default=256,\n",
    "    help=\"the batch size of the data during the training process\")\n",
    "\n",
    "parser.add_argument(\"--hidden_size\",\n",
    "                    type=int,\n",
    "                    default=256,\n",
    "                    help=\"the size of the hidden nodes of MLP_reg \")\n",
    "\n",
    "parser.add_argument(\n",
    "    \"--optimizer\",\n",
    "    choices=[\n",
    "        \"Adam\", \"SGD\", \"ASGD\", \"Rprop\", \"Adagrad\", \"Adadelta\", \"RMSprop\",\n",
    "        \"Adamax\", \"SparseAdam\", \"LBFGS\"\n",
    "    ],\n",
    "    default=\"Adam\",\n",
    "    help=\"the name of the optimizer\",\n",
    ")\n",
    "\n",
    "parser.add_argument(\n",
    "    \"--num_epoch\",\n",
    "    type=int,\n",
    "    default=10,\n",
    "    help=\"the number of epoch\",\n",
    ")\n",
    "parser.add_argument(\n",
    "    \"--input_logic_config\",\n",
    "    type=bool,\n",
    "    default=False,\n",
    "    help=\n",
    "    \"determine whether to use a yaml file as the overall input of the logic_discriptor, this is needed when have other format of dataset\"\n",
    ")\n",
    "parser.add_argument(\n",
    "    \"--input_logic_config_dict\",\n",
    "    type=str,\n",
    "    default=\"config/input_config/agent/investor_imitator/logic_discriptor.yml\",\n",
    "    help=\n",
    "    \"determine the path of a yaml file as the overall input of the logic_discriptor\"\n",
    ")\n",
    "args = parser.parse_args(args=[])\n",
    "a = logic_discriptor(args)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Enviornment Construction and Reinforcement Learning"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/sunshuo/miniconda3/envs/TradeMaster/lib/python3.7/site-packages/tqdm/auto.py:22: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
      "  from .autonotebook import tqdm as notebook_tqdm\n"
     ]
    },
    {
     "ename": "KeyboardInterrupt",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mKeyboardInterrupt\u001b[0m                         Traceback (most recent call last)",
      "\u001b[0;32m/tmp/ipykernel_4426/2625097345.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m     76\u001b[0m \u001b[0margs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mparser\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mparse_args\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     77\u001b[0m \u001b[0magent\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mAgent\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 78\u001b[0;31m \u001b[0magent\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtrain_with_valid\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     79\u001b[0m \u001b[0magent\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtest\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/qml/TradeMaster/tutorial/agent/Investor_Imitator/RL/RL.py\u001b[0m in \u001b[0;36mtrain_with_valid\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m    176\u001b[0m             \u001b[0mactions\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    177\u001b[0m             \u001b[0;32mwhile\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mdone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 178\u001b[0;31m                 \u001b[0maction\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mselect_action\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstate\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    179\u001b[0m                 \u001b[0mstate\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mreward\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtrain_env_instance\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstep\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0maction\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    180\u001b[0m                 \u001b[0mactions\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0maction\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/qml/TradeMaster/tutorial/agent/Investor_Imitator/RL/RL.py\u001b[0m in \u001b[0;36mselect_action\u001b[0;34m(self, state)\u001b[0m\n\u001b[1;32m    143\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0mselect_action\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstate\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    144\u001b[0m         \u001b[0mstate\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfrom_numpy\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstate\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfloat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcuda\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 145\u001b[0;31m         \u001b[0mprobs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpolicy\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstate\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    146\u001b[0m         \u001b[0mm\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mCategorical\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mprobs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    147\u001b[0m         \u001b[0maction\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mm\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msample\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/miniconda3/envs/TradeMaster/lib/python3.7/site-packages/torch/nn/modules/module.py\u001b[0m in \u001b[0;36m_call_impl\u001b[0;34m(self, *input, **kwargs)\u001b[0m\n\u001b[1;32m   1128\u001b[0m         if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks\n\u001b[1;32m   1129\u001b[0m                 or _global_forward_hooks or _global_forward_pre_hooks):\n\u001b[0;32m-> 1130\u001b[0;31m             \u001b[0;32mreturn\u001b[0m \u001b[0mforward_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0minput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   1131\u001b[0m         \u001b[0;31m# Do not call functions when jit is used\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1132\u001b[0m         \u001b[0mfull_backward_hooks\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnon_full_backward_hooks\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/qml/TradeMaster/tutorial/agent/Investor_Imitator/model/net.py\u001b[0m in \u001b[0;36mforward\u001b[0;34m(self, x)\u001b[0m\n\u001b[1;32m     33\u001b[0m         \u001b[0;31m# x = torch.nn.Sigmoid()(x)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     34\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 35\u001b[0;31m         \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0maffline1\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     36\u001b[0m         \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mSigmoid\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     37\u001b[0m         \u001b[0maction_scores\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0maffline2\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0munsqueeze\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/miniconda3/envs/TradeMaster/lib/python3.7/site-packages/torch/nn/modules/module.py\u001b[0m in \u001b[0;36m_call_impl\u001b[0;34m(self, *input, **kwargs)\u001b[0m\n\u001b[1;32m   1128\u001b[0m         if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks\n\u001b[1;32m   1129\u001b[0m                 or _global_forward_hooks or _global_forward_pre_hooks):\n\u001b[0;32m-> 1130\u001b[0;31m             \u001b[0;32mreturn\u001b[0m \u001b[0mforward_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0minput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   1131\u001b[0m         \u001b[0;31m# Do not call functions when jit is used\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1132\u001b[0m         \u001b[0mfull_backward_hooks\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnon_full_backward_hooks\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/miniconda3/envs/TradeMaster/lib/python3.7/site-packages/torch/nn/modules/linear.py\u001b[0m in \u001b[0;36mforward\u001b[0;34m(self, input)\u001b[0m\n\u001b[1;32m    112\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    113\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0mforward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mTensor\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m->\u001b[0m \u001b[0mTensor\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 114\u001b[0;31m         \u001b[0;32mreturn\u001b[0m \u001b[0mF\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlinear\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mweight\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbias\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    115\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    116\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0mextra_repr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m->\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
     ]
    }
   ],
   "source": [
    "from agent.Investor_Imitator.RL.RL import Agent,env_creator,load_yaml\n",
    "import argparse\n",
    "parser = argparse.ArgumentParser()\n",
    "parser.add_argument(\n",
    "    \"--env_name\",\n",
    "    choices=[\"portfolio\"],\n",
    "    default=\"portfolio\",\n",
    "    help=\"the name of TradingEnv \",\n",
    ")\n",
    "parser.add_argument(\n",
    "    \"--dict_trained_model\",\n",
    "    default=\"result/PM/invest_imitator/trained_model\",\n",
    "    help=\"the dict of the trained model \",\n",
    ")\n",
    "\n",
    "parser.add_argument(\n",
    "    \"--train_env_config_dict\",\n",
    "    default=\n",
    "    \"config/input_config/env/portfolio/portfolio_for_investor_imitator/train.yml\",\n",
    "    help=\"the dict of the train config of TradingEnv \",\n",
    ")\n",
    "\n",
    "parser.add_argument(\n",
    "    \"--valid_env_config_dict\",\n",
    "    default=\n",
    "    \"config/input_config/env/portfolio/portfolio_for_investor_imitator/valid.yml\",\n",
    "    help=\"the dict of the valid config of TradingEnv \",\n",
    ")\n",
    "\n",
    "parser.add_argument(\n",
    "    \"--test_env_config_dict\",\n",
    "    default=\n",
    "    \"config/input_config/env/portfolio/portfolio_for_investor_imitator/test.yml\",\n",
    "    help=\"the dict of the test config of TradingEnv \",\n",
    ")\n",
    "\n",
    "parser.add_argument(\n",
    "    \"--num_epochs\",\n",
    "    type=int,\n",
    "    default=10,\n",
    "    help=\"the number of training epoch\",\n",
    ")\n",
    "\n",
    "parser.add_argument(\n",
    "    \"--random_seed\",\n",
    "    type=int,\n",
    "    default=12345,\n",
    "    help=\"the number of training epoch\",\n",
    ")\n",
    "\n",
    "parser.add_argument(\n",
    "    \"--result_dict\",\n",
    "    type=str,\n",
    "    default=\"result/PM/invest_imitator/test_result/\",\n",
    "    help=\"the dict of the result of the test\",\n",
    ")\n",
    "parser.add_argument(\n",
    "    \"--input_config_RL\",\n",
    "    type=bool,\n",
    "    default=False,\n",
    "    help=\"whether to use yaml as the config\",\n",
    ")\n",
    "parser.add_argument(\n",
    "    \"--input_config_dict_RL\",\n",
    "    type=str,\n",
    "    default=\"config/input_config/agent/investor_imitator/RL.yml\",\n",
    "    help=\"the dict of yaml\",\n",
    ")\n",
    "parser.add_argument(\n",
    "    \"--seed\",\n",
    "    type=int,\n",
    "    default=12345,\n",
    "    help=\"the random seed\",\n",
    ")\n",
    "\n",
    "args = parser.parse_args(args=[])\n",
    "agent = Agent(args)\n",
    "agent.train_with_valid()\n",
    "agent.test()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For the simplicity, we use the yaml file to store the configuration for the RL environment construction, which can be found [here](https://github.com/qinmoelei/TradeMaster_reframe/tree/master/tutorial/config/input_config/env/PM/portfolio_for_IMIT)\n",
    "but first, let us import the package we might use"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Test Visualization"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>daily_return</th>\n",
       "      <th>total assets</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.000000</td>\n",
       "      <td>100000.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.002944</td>\n",
       "      <td>100294.362806</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.018698</td>\n",
       "      <td>102169.639479</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.014027</td>\n",
       "      <td>103602.724627</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>-0.000181</td>\n",
       "      <td>103583.978346</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   daily_return   total assets\n",
       "0      0.000000  100000.000000\n",
       "1      0.002944  100294.362806\n",
       "2      0.018698  102169.639479\n",
       "3      0.014027  103602.724627\n",
       "4     -0.000181  103583.978346"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "test_result=pd.read_csv(\"result/PM/invest_imitator/test_result/result.csv\",index_col=0)\n",
    "test_result.head(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from matplotlib import pyplot as plt\n",
    "x = range(len(test_result))\n",
    "y = test_result[\"total assets\"].tolist()\n",
    "plt.plot(x, y)  \n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.7.13 ('TradeMaster')",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.13"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "a1f97403911abd3f02553c8f2b0c54537fddc7efadd9f5d3e31784db6e40c347"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
